package cn.ljy.mes.service.impl;

import cn.ljy.authority.service.impl.IBaseService;
import cn.ljy.common.exception.model.MyConfirmException;
import cn.ljy.common.exception.model.MyServiceException;
import cn.ljy.common.exception.model.MyWebException;
import cn.ljy.mes.dao.mapper.*;
import cn.ljy.mes.model.WmsWarehouseArea;
import cn.ljy.mes.model.WmsWarehouseSeat;
import cn.ljy.mes.model.query.WmsMaterialInventoryDetailQuery;
import cn.ljy.mes.model.query.WmsMaterialInventoryDetailRelocationLogQuery;
import cn.ljy.mes.model.query.WmsWarehouseAreaQuery;
import cn.ljy.mes.model.query.WmsWarehouseSeatQuery;
import cn.ljy.mes.service.WmsWarehouseAreaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
//@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor= MyRollBackException.class)
@Validated//表示开启sprint的校检框架，会自动扫描方法里的@Valid（@Valid注解一般写在接口即可）
@Slf4j
public class IWmsWarehouseAreaService extends IBaseService<WmsWarehouseArea, WmsWarehouseAreaQuery> implements WmsWarehouseAreaService {
    @Autowired
    private WmsWarehouseMapper wmsWarehouseMapper;
    @Autowired
    private WmsWarehouseSeatMapper wmsWarehouseSeatMapper;
    @Autowired
    private WmsMaterialInventoryMapper materialInventoryMapper;
    @Autowired
    private WmsMaterialInventoryDetailMapper materialInventoryDetailMapper;
    @Autowired
    private WmsMaterialInventoryDetailRelocationLogMapper materialInventoryDetailRelocationLogMapper;

    @Override
    protected void enrichEntityFields(WmsWarehouseArea wmsWarehouseArea){
        if(wmsWarehouseArea!=null){
            //获取库区下的库位数量
            WmsWarehouseSeatQuery wmsWarehouseSeatQuery=new WmsWarehouseSeatQuery();
            wmsWarehouseSeatQuery.setWarehouseArea(wmsWarehouseArea);
            wmsWarehouseArea.setSeatNumber(wmsWarehouseSeatMapper.count(wmsWarehouseSeatQuery));
            //获取库区下的物料存储位
            WmsMaterialInventoryDetailQuery materialInventoryDetailQuery=new WmsMaterialInventoryDetailQuery();
            WmsWarehouseSeat warehouseSeat=new WmsWarehouseSeat();
            warehouseSeat.setWarehouseArea(wmsWarehouseArea);
            materialInventoryDetailQuery.setWarehouseSeat(warehouseSeat);
            wmsWarehouseArea.setMaterialInventoryDetailNumber(materialInventoryDetailMapper.count(materialInventoryDetailQuery));
        }
    }

    @Override
    protected void beforeSave(WmsWarehouseArea wmsWarehouseArea) {
        if(wmsWarehouseArea.getWarehouse()==null||wmsWarehouseArea.getWarehouse().getId()==null){
            throw new MyWebException("验证失败：请先选择所属仓库");
        }
    }

    @Override
    protected void beforeUpdate(WmsWarehouseArea wmsWarehouseArea) {
        //仓库不是必须要传递，但如果传递了id就不能为空
        if(wmsWarehouseArea.getWarehouse()!=null&&wmsWarehouseArea.getWarehouse().getId()==null){
            throw new MyWebException("验证失败：请先选择所属仓库");
        }
    }

    @Override
    protected void beforeDelete(Serializable[] ids) {
        Map<String,String> errorMessageMap=new HashMap();
        for(Serializable id:ids){
            if(id!=null){
                //获取仓库详情
                WmsWarehouseArea warehouseArea=mapper.findById(id);
                if(warehouseArea!=null){
                    //获取仓库下的库位数量
                    WmsWarehouseSeatQuery wmsWarehouseSeatQuery=new WmsWarehouseSeatQuery();
                    wmsWarehouseSeatQuery.setWarehouseArea(new WmsWarehouseArea(id.toString()));
                    int warehouseSeatNumber=wmsWarehouseSeatMapper.count(wmsWarehouseSeatQuery);
                    if(warehouseSeatNumber>0){
                        errorMessageMap.put(warehouseArea.getName(),String.valueOf(warehouseSeatNumber));
                    }
                }
            }
        }
        //确定是否抛出错误信息
        if(errorMessageMap.size()>0){
            throw new MyConfirmException("%s已存在%s个库位",errorMessageMap);
        }
    }

    @Override
    protected void beforeForceDelete(Serializable[] ids) {
        Map<String,Integer> errorMessageMap=new HashMap();
        List<WmsWarehouseSeat> allSeats=new ArrayList<>();//定义和获取所有库区下的库位信息
        for(Serializable id:ids){
            if(id!=null){
                WmsWarehouseArea warehouseArea=mapper.findById(id);
                //1.获取库区下的库位集合
                WmsWarehouseSeatQuery wmsWarehouseSeatQuery=new WmsWarehouseSeatQuery();
                wmsWarehouseSeatQuery.setWarehouseArea(warehouseArea);
                List<WmsWarehouseSeat> seats = wmsWarehouseSeatMapper.findAll(wmsWarehouseSeatQuery);
                allSeats.addAll(seats);
                //2.判断库位是否已经使用
                for(WmsWarehouseSeat seat:seats){
                    WmsMaterialInventoryDetailQuery materialInventoryDetailQuery=new WmsMaterialInventoryDetailQuery();
                    materialInventoryDetailQuery.setWarehouseSeat(seat);
                    int materialInventoryDetailNumber=materialInventoryDetailMapper.count(materialInventoryDetailQuery);
                    if(materialInventoryDetailNumber>0){
                        errorMessageMap.put(seat.getName(),materialInventoryDetailNumber);
                        throw new MyServiceException(String.format("删除失败：库位%s正被%d个物料占用，无法删除！",seat.getName(),materialInventoryDetailNumber));
                    }
                    //3.先判断库位是否已经有使用的日志，即使当前已经没有物料在库位中，也不允许删除库位信息
                    //3.1 判断源库位
                    WmsMaterialInventoryDetailRelocationLogQuery materialInventoryDetailRelocationLogQuery=new WmsMaterialInventoryDetailRelocationLogQuery();
                    materialInventoryDetailRelocationLogQuery.setWarehouseSeatOfSource(seat);
                    int materialInventoryDetailRelocationLogNumber=materialInventoryDetailRelocationLogMapper.count(materialInventoryDetailRelocationLogQuery);
                    if(materialInventoryDetailRelocationLogNumber>0){
                        throw new MyServiceException(String.format("删除失败：库位%s虽然已经没有物料在使用，但是已经有出库的使用记录，无法删除！",seat.getName()));
                    }
                    //3.2 判断目标库位
                    materialInventoryDetailRelocationLogQuery=new WmsMaterialInventoryDetailRelocationLogQuery();
                    materialInventoryDetailRelocationLogQuery.setWarehouseSeatOfTarget(seat);
                    materialInventoryDetailRelocationLogNumber=materialInventoryDetailRelocationLogMapper.count(materialInventoryDetailRelocationLogQuery);
                    if(materialInventoryDetailRelocationLogNumber>0){
                        throw new MyServiceException(String.format("删除失败：库位%s虽然已经没有物料在使用，但是已经有入库的使用记录，无法删除！",seat.getName()));
                    }
                }

            }
        }
        //如果没有错误信息，则可以执行删除
        wmsWarehouseSeatMapper.deleteAllIn(allSeats);//移除所有库位
//        //定义错误信息
//        StringBuilder errorMessage=new StringBuilder();
//        if(errorMessageMap.size()>0){
//            int index=0;//索引
//            errorMessage.append("强制删除失败:");
//            //循环处理错误信息
//            for(String name:errorMessageMap.keySet()){
//                errorMessage.append(String.format("库位%s正被%d种物料占用",name,errorMessageMap.get(name)));
//                if(index==errorMessageMap.size()-1){//最后一个不进行处理，是为了交给前端来决定最后一句话的符号结尾。
////                    errorMessage.append("。");
//                }else{
//                    errorMessage.append("，");
//                }
//                index++;
//            }
//            throw new MyServiceException(errorMessage.toString());
//        }else{//如果没有错误信息，则可以执行删除
//            wmsWarehouseSeatMapper.deleteAllIn(allSeats);//移除所有库位
//        }
    }
}
